home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / threads / Threads2.c < prev    next >
C/C++ Source or Header  |  1991-01-10  |  8KB  |  347 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.   endcopyright */
  15.  
  16. /*
  17.  * Threads2.c 
  18.  *
  19.  * Demers, January 10, 1991 1:16:42 pm PST
  20.  */
  21.  
  22. #include "xr/BasicTypes.h"
  23. #include "xr/Errno.h"
  24. #include "xr/Threads.h"
  25. #include "xr/ThreadsBackdoor.h"
  26. #include "xr/ThreadsPrivate.h"
  27. #include "xr/ThreadsSignalsPrivate.h"
  28. #include "xr/ThreadsMsgPrivate.h"
  29.  
  30.  
  31. void
  32. XR_GetCurrent (result)
  33.     struct XR_CTRep *result;
  34. {
  35.     result->ct_thread = XR_currThread;
  36.     result->ct_gen = XR_currThread->t_gen;
  37. }
  38.  
  39.  
  40. void
  41. XR_Yield ()
  42. {
  43.     XR_Switch(NIL, XR_SSTAT_READY, XR_SWSTAT_THREAD);
  44. }
  45.  
  46.  
  47.  
  48. int
  49. XR_PauseAbortable (ticks)
  50.     XR_Ticks ticks;
  51. {
  52.     XR_CV cv;
  53.     if( ticks == 0 ) return( XR_AbortPending() ? -1 : 0 );
  54.     cv = &(XR_currThread->t_timerCV);
  55.     XR_EnableAborts( cv );
  56.     XR_SetTimeout( cv, ticks );
  57.     return( XR_WaitCV(cv, NIL) );
  58. }
  59.  
  60.  
  61. void
  62. XR_PauseNotAbortable(ticks)
  63.     XR_Ticks ticks;
  64. {
  65.     XR_CV cv;
  66.     if( ticks == 0 ) return;
  67.     cv = &(XR_currThread->t_timerCV);
  68.     XR_DisableAborts( cv );
  69.     XR_SetTimeout( cv, ticks );
  70.     (void)XR_WaitCV(cv, NIL);
  71. }
  72.  
  73.  
  74. int
  75. XR_CancelAbort (ct)
  76.     XR_CT ct;
  77. {
  78.     XR_Thread t;
  79.     if( ct == NIL ) {
  80.         t = XR_currThread;
  81.     } else {
  82.     if( (t = ct->ct_thread) == NIL ) return(-1);
  83.     if( t->t_gen != ct->ct_gen ) return(-1);
  84.     }
  85.     t->t_abortRequest = FALSE;
  86.     return(0);
  87. }
  88.  
  89.  
  90. /*
  91.  * ??? this may be too conservative about holding the MetaLock ???
  92.  */
  93.  
  94. int
  95. XR_AbortCT (ct)
  96.     XR_CT ct;
  97. {
  98.     XR_Thread t = ct->ct_thread;
  99.     XR_Thread each = XR_currThread;
  100.     XR_WQ wq;
  101.     bool doSetReady = FALSE;
  102.  
  103.     if( t == NIL ) return(-1);
  104.  
  105.     XR_MonitorEntry(&(t->t_ml));
  106.     if( t->t_gen != ct->ct_gen ) {
  107.         XR_MonitorExit(&(t->t_ml));
  108.         return(-1);
  109.     }
  110.  
  111.     t->t_abortRequest = TRUE;
  112.     XR_LockMeta("AbortCT 0");
  113.     for(;;) {
  114.         if( !(t->t_abortRequest) /* process has seen abort request */
  115.         ) {
  116.             break;
  117.         }
  118.         if( (t->t_sStat != XR_SSTAT_WAIT_CV)    /* already woke up */
  119.                 || (!(t->t_abortable))        /* not abortable */
  120.                 || ((wq = t->t_wq) == NIL)     /* in notify or timeout */
  121.         ) {
  122.             break;
  123.         }
  124.         if( XR_TryGSL(&(wq->wq_gsl)) /* got the wait queue */ ) {
  125.         if( t->t_wq == wq    /* ... and not in notify or timeout */ ) {
  126.             XR_RemWQ(t);
  127.         doSetReady = TRUE;
  128.         break;        /* XR_ReleaseGSL happens below */
  129.         }
  130.         XR_ReleaseGSL(&(wq->wq_gsl));
  131.     } else {
  132.         /* can't acquire the wait queue, so do a directed    */
  133.         /*   yield to somebody who might hold it ...    */
  134.         XR_Thread limit = &(XR_sysArea->sa_threadPool[XR_maxThreads]);
  135.         XR_Thread holder = NIL;
  136.         int i;
  137.         XR_UnlockMeta();
  138.         for( i = 0; i < XR_maxThreads; i++ ) {
  139.             if( ++each >= limit ) each = &(XR_sysArea->sa_threadPool[0]);
  140.             if( each->t_wq == wq ) { holder = each; break; }
  141.         }
  142.         XR_Switch(holder, XR_SSTAT_READY, XR_SWSTAT_THREAD);
  143.         XR_LockMeta("AbortCT 1");
  144.     }
  145.     }
  146.     XR_UnlockMeta();
  147.     XR_MonitorExit(&(t->t_ml));
  148.     if( doSetReady ) {
  149.         XR_VPE best = XR_SetThreadReady(t);
  150.         XR_ReleaseGSL(&(wq->wq_gsl));
  151.         if( best == XR_vpe ) {
  152.             XR_Switch(t, XR_SSTAT_READY, XR_SWSTAT_THREAD);
  153.         } else if( best != NIL ) {
  154.             XR_RequestResched(best);
  155.         }
  156.     }
  157.     XR_CheckReschedRequest();
  158.     return(0);
  159. }
  160.  
  161.  
  162.  
  163. int
  164. XR_ValidateCT (ct)
  165.     XR_CT ct;
  166. {
  167.     XR_Thread t = ct->ct_thread;
  168.     
  169.     if( (t == NIL) || (t->t_gen != ct->ct_gen) )
  170.         return(-1);
  171.     return(0);
  172. }
  173.  
  174.  
  175. /*
  176.  * Per-thread client data
  177.  *
  178.  * The initializations support the OBSOLETE threadProperty stuff ...
  179.  */
  180.  
  181. static struct XR_MLRep
  182. XR_threadDataRegistrationsLock = XR_NULL_ML_REP;
  183.  
  184. typedef struct XR_ThreadDataRegistrationRep {
  185.     XR_Pointer tdr_key;
  186.     bool tdr_inherited;
  187. } *XR_ThreadDataRegistration;
  188.  
  189. static struct XR_ThreadDataRegistrationRep
  190. XR_threadDataRegistrations[XR_NUM_PER_THREAD_DATA] = {
  191.     { 1,    FALSE    },    /* t_property */
  192.     { 2,    TRUE    },    /* t_inheritedProperty */
  193.     { 0,    FALSE    }
  194. };
  195.  
  196.  
  197. int
  198. XR_GetPerThreadDataID(key, create, inherit)
  199.     XR_Pointer key;
  200.     bool create;
  201.     bool inherit;
  202. {
  203.     int i, ans;
  204.  
  205.     if( XR_currThread == NIL ) {
  206.         XR_Panic("GetPerThreadDataID 0");
  207.     }
  208.     if( key == 0 ) {
  209.         XR_SetErrno(EINVAL);
  210.         return (-1);
  211.     }
  212.  
  213.     XR_MonitorEntry(&XR_threadDataRegistrationsLock);
  214.     for( i = 0; ; i++ ) {
  215.         if( i >= XR_NUM_PER_THREAD_DATA ) {
  216.             ans = (-1); XR_SetErrno(ENOMEM);
  217.             goto Out;
  218.         }
  219.         if( XR_threadDataRegistrations[i].tdr_key == NIL ) {
  220.             if( create ) {
  221.                 XR_threadDataRegistrations[i].tdr_key = key;
  222.                 XR_threadDataRegistrations[i].tdr_inherited = inherit;
  223.                 ans = ((int)(&(XR_currThread->t_perThreadData[i])))
  224.                         - ((int)(XR_currThread));
  225.             } else {
  226.                 ans = (-1); XR_SetErrno(EINVAL);
  227.             }
  228.             goto Out;
  229.         }
  230.         if( XR_threadDataRegistrations[i].tdr_key == key ) {
  231.             if( create ) {
  232.                 ans = (-1); XR_SetErrno(EINVAL);
  233.             } else {
  234.                 ans = ((int)(&(XR_currThread->t_perThreadData[i])))
  235.                         - ((int)(XR_currThread));
  236.             }
  237.             goto Out;
  238.         }
  239.     }
  240.   Out:
  241.     XR_MonitorExit(&XR_threadDataRegistrationsLock);
  242.     return ans;
  243. }
  244.  
  245.  
  246. void
  247. XR_InheritPerThreadData(from, to)
  248.     XR_Thread from;
  249.     XR_Thread to;
  250. {
  251.     XR_ThreadDataRegistration reg;
  252.     XR_Pointer *pTo;
  253.     int i;
  254.  
  255.     reg = XR_threadDataRegistrations;
  256.     pTo = to->t_perThreadData;
  257.     for( i = 0; i < XR_NUM_PER_THREAD_DATA; i++ ) {
  258.         if( reg->tdr_inherited ) {
  259.             *pTo++ = from->t_perThreadData[i];
  260.         } else {
  261.             *pTo++ = NIL;
  262.         }
  263.         reg++;
  264.     }
  265. }
  266.  
  267.  
  268.     /* OBSOLETE */
  269.  
  270.     int
  271.     XR_GetPerThreadDataOffset(key, create)
  272.         XR_Pointer key;
  273.         bool create;
  274.     {
  275.         return XR_GetPerThreadDataID(key, create, FALSE);
  276.     }
  277.  
  278.     XR_Pointer *
  279.     XR_GetPerThreadDataSlot(byteOffset)
  280.         int byteOffset;
  281.     {
  282.         return XR_GetPerThreadDataAddress(byteOffset);
  283.     }
  284.  
  285.  
  286.     XR_Pointer
  287.     XR_GetThreadProperty ()
  288.     {
  289.         return( XR_currThread->t_perThreadData[0] );
  290.     }
  291.  
  292.  
  293.     XR_Pointer
  294.     XR_GetThreadInheritedProperty ()
  295.     {
  296.         return( XR_currThread->t_perThreadData[1] );
  297.     }
  298.  
  299.  
  300.     void
  301.     XR_SetThreadProperty (p)
  302.         XR_Pointer p;
  303.     {
  304.         XR_currThread->t_perThreadData[0] = p;
  305.     }
  306.  
  307.  
  308.     void
  309.     XR_SetThreadInheritedProperty (p)
  310.         XR_Pointer p;
  311.     {
  312.         XR_currThread->t_perThreadData[1] = p;
  313.     }
  314.  
  315.  
  316.  
  317. void
  318. XR_SetPriority (pri)
  319.     XR_Pri pri;
  320. /*
  321.     Set priority of current thread.
  322.     If priority increases, this won't be reflected in XR_vpe->vpe_pri
  323.       until the next thread switch, but that's benign.
  324.     Note you're not allowed to set priority to XR_PRI_SYS_EXCLUSIVE
  325.       using this (obsolescent) interface -- see ThreadsSchedCtl.h.
  326. */
  327. {
  328.     if( pri > XR_PRI_LAST ) {
  329.         pri = XR_PRI_LAST;
  330.     } else if( pri <= XR_PRI_IDLE ) {
  331.         pri = XR_PRI_IDLE;
  332.     }
  333.     if( (pri == XR_PRI_IDLE)
  334.             && (XR_currThread->t_index >= XR_sysArea->sa_numVP) ) {
  335.         pri += 1;
  336.     }
  337.     if( pri == XR_PRI_SYS_EXCLUSIVE ) {
  338.         pri -= 1;
  339.     }
  340.     XR_currThread->t_pri = pri;
  341.     XR_Yield();
  342. }
  343.  
  344.  
  345.  
  346.  
  347.